#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <unistd.h>

void echo(const std::string& text) {
    std::cerr << text << std::endl;
    if(!isatty(STDOUT_FILENO)){
        std::cout << text << std::endl;
    }
}

void printHelp() {
    std::cerr << "\033[32m" << "功能：" << "\033[0m" << std::endl;
    std::cerr << "  " << "显示文本内容或文件内容，可以选择转换为大写或小写。" << std::endl;
    std::cerr << "\033[32m" << "用法：" << "\033[0m" << std::endl;
    std::cerr << "  " << "echo [-n] [-e | -f] [text or filename]" << std::endl;
    std::cerr << "\033[32m" << "选项：" << "\033[0m" << std::endl;
    std::cerr << "  " << "-n" << std::endl;
    std::cerr << "    " << "显示行号。" << std::endl;
    std::cerr << "  " << "-e" << std::endl;
    std::cerr << "    " << "将文本转换为大写。" << std::endl;
    std::cerr << "  " << "-f" << std::endl;
    std::cerr << "    " << "将文本转换为小写。" << std::endl;
    std::cerr << "\033[32m" << "参数：" << "\033[0m" << std::endl;
    std::cerr << "  " << "text or filename" << std::endl;
    std::cerr << "    " << "要显示的文本或文件名。" << std::endl;
}

std::string readFile(const std::string& filename) {
    std::ifstream file(filename);
    std::string content;
    if (file.is_open()) {
        std::ostringstream oss;
        oss << file.rdbuf();
        content = oss.str();
    } else {
        std::cerr << "Error: Unable to open file " << filename << std::endl;
    }
    return content;
}

void displayFileContentToUpper(const std::string& content, bool showLineNumbers) {
    std::istringstream iss(content);
    std::string line;
    int lineNumber = 1;
    while (std::getline(iss, line)) {
        if (showLineNumbers) {
            std::cerr << lineNumber << " ";
            if(!isatty(STDOUT_FILENO)){
                std::cout << lineNumber << " ";
            }
        }
        std::transform(line.begin(), line.end(), line.begin(), ::toupper);
        std::cerr << line << std::endl;
        if(!isatty(STDOUT_FILENO)){
            std::cout << line << std::endl;
        }
        ++lineNumber;
    }
}

void displayFileContentToLower(const std::string& content, bool showLineNumbers) {
    std::istringstream iss(content);
    std::string line;
    int lineNumber = 1;
    while (std::getline(iss, line)) {
        if (showLineNumbers) {
            std::cerr << lineNumber << " ";
            if(!isatty(STDOUT_FILENO)){
                std::cout << lineNumber << " ";
            }            
        }
        std::transform(line.begin(), line.end(), line.begin(), ::tolower);
        std::cerr << line << std::endl;
        if(!isatty(STDOUT_FILENO)){
            std::cout << line << std::endl;
        }        
        ++lineNumber;
    }
}

int main(int argc, char* argv[]) {
    if(argc == 2 && std::string(argv[1]) == "--help") {
    	printHelp(); // 判断是否输出帮助信息
    	return 0;
    }
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " [-n] [-e] [-f] [text or filename]" << std::endl;
        return 1;
    }

    bool showLineNumbers = false;
    bool toUpper = false;
    bool toLower = false;
    bool if_file = false;
    std::int32_t text_count = 0;
    std::string text;

    // Extract options and check if text to echo is provided
    for (int i = 1; i < argc; ++i) {
        std::string arg = argv[i];
        if (arg == "-n") {
            if_file = true;
            showLineNumbers = true;
        } else if (arg == "-e") {
            if_file = true;
            toUpper = true;
        } else if (arg == "-f") {
            if_file = true;
            toLower = true;
        }
        else {
            text_count++;
            if (!text.empty()) {
                text += " ";
            }
            text += arg;
        }
    }

    if (if_file && text_count > 1) {
        std::cerr << "\033[31m" << "if exit \"-n\" option, the text_count could be 1 only" << "\033[0m" << std::endl;
        return 1;
    }
    if (!if_file) {
        // If no -e or -f option specified, simply echo the provided text
        echo(text);
    } else {
        // If -e or -f option specified, read file if provided, else treat text as input
        if (text_count < 1) {
            std::cerr << "No input provided after option." << std::endl;
            return 1;
        }
        std::string content;
        if (if_file || toLower || toUpper) {
            // If -e or -f option specified, read file content
            content = readFile(text);
            if (content.empty()) return 1;
            if (toUpper) {
                displayFileContentToUpper(content, showLineNumbers);
            } else if (toLower) {
                displayFileContentToLower(content, showLineNumbers);
            }
            else {
                std::istringstream iss(content);
                std::string line;
                int lineNumber = 1;
                while (std::getline(iss, line)) {
                    if (showLineNumbers) {
                        std::cerr << lineNumber << " ";
                        if(!isatty(STDOUT_FILENO)){
                            std::cout << lineNumber << " ";
                        }            
                    }
                    std::cerr << line << std::endl;
                    if(!isatty(STDOUT_FILENO)){
                        std::cout << line << std::endl;
                    }        
                    ++lineNumber;
                }
            }
        }
    }

    return 0;
}